package com.huanxing.cloud.upms.admin.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huanxing.cloud.common.core.constant.CommonConstants;
import com.huanxing.cloud.common.core.entity.Result;
import com.huanxing.cloud.common.log.annotation.SysLog;
import com.huanxing.cloud.security.utils.SecurityUtils;
import com.huanxing.cloud.upms.admin.service.ISysMenuService;
import com.huanxing.cloud.upms.admin.service.ISysRoleService;
import com.huanxing.cloud.upms.common.constant.UpmsConstans;
import com.huanxing.cloud.upms.common.dto.MenuTree;
import com.huanxing.cloud.upms.common.dto.SysMenuRequestDTO;
import com.huanxing.cloud.upms.common.entity.SysMenu;
import com.huanxing.cloud.upms.common.utils.TreeUtil;
import com.huanxing.cloud.upms.common.vo.MenuVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 菜单管理
 *
 * @author lijx
 * @since 2022/2/26 16:40
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/menu")
@Api(value = "menu", tags = "菜单管理")
public class SysMenuController {

  private final ISysMenuService sysMenuService;
  private final ISysRoleService sysRoleService;

  /**
   * 获取所有菜单和权限
   *
   * @return 树形菜单
   */
  @ApiOperation(value = "查询树形菜单集合")
  @PreAuthorize("hasAuthority('upms:sysmenu:page')")
  @GetMapping(value = "/tree")
  public Result getAllTree() {
    List<MenuTree> menuTreeList =
        TreeUtil.buildTree(
            new ArrayList<>(
                sysMenuService.list(Wrappers.<SysMenu>lambdaQuery().orderByAsc(SysMenu::getSort))),
            CommonConstants.PARENT_ID);
    return Result.success(menuTreeList);
  }

  @ApiOperation(value = "查询当前用户的树形菜单集合")
  @GetMapping
  public Result getUserMenu() {
    Set<MenuVO> all = new HashSet<>();
    List<String> roles = sysRoleService.findRoleIdsByUserId(SecurityUtils.getUser().getUserId());
    roles.forEach(roleId -> all.addAll(sysMenuService.findMenuByRoleId(roleId)));
    List<MenuTree> menuTreeList =
        all.stream()
            .filter(menuVo -> CommonConstants.MENU_TYPE_0.equals(menuVo.getType()))
            .map(MenuTree::new)
            .sorted(Comparator.comparingInt(MenuTree::getSort))
            .collect(Collectors.toList());
    return Result.success(TreeUtil.build(menuTreeList, CommonConstants.PARENT_ID));
  }

  @ApiOperation(value = "查询角色的菜单集合")
  @PreAuthorize("hasAuthority('upms:sysmenu:get')")
  @GetMapping("/tree/{roleId}")
  public Result<List<String>> getRoleMenus(@PathVariable String roleId) {
    return Result.success(
        sysMenuService.findMenuByRoleId(roleId).stream()
            .map(MenuVO::getId)
            .collect(Collectors.toList()));
  }

  @ApiOperation(value = "通过ID查询")
  @PreAuthorize("hasAuthority('upms:sysmenu:get')")
  @GetMapping("/{id}")
  public Result getById(@PathVariable String id) {
    return Result.success(sysMenuService.getById(id));
  }

  @ApiOperation(value = "菜单新增")
  @SysLog("新增菜单")
  @PreAuthorize("hasAuthority('upms:sysmenu:add')")
  @PostMapping
  public Result add(@RequestBody SysMenu sysMenu) {
    return Result.success(sysMenuService.save(sysMenu));
  }

  @ApiOperation(value = "菜单编辑")
  @SysLog("编辑菜单")
  @PreAuthorize("hasAuthority('upms:sysmenu:edit')")
  @PutMapping
  public Result edit(@RequestBody SysMenu sysMenu) {
    return Result.success(sysMenuService.updateById(sysMenu));
  }

  @ApiOperation(value = "菜单删除")
  @SysLog("删除菜单")
  @PreAuthorize("hasAuthority('upms:sysmenu:del')")
  @DeleteMapping("/{id}")
  public Result del(@PathVariable("id") String id) {
    SysMenu sysMenu = new SysMenu();
    sysMenu.setParentId(id);
    long count = sysMenuService.count(Wrappers.lambdaQuery(sysMenu));
    if (count > 0) {
      return Result.fail("请先删除下级菜单");
    }
    return Result.success(sysMenuService.removeById(id));
  }

  @ApiOperation(value = "菜单权限新增")
  @SysLog("新增菜单权限")
  @PreAuthorize("hasAuthority('upms:sysmenu:add')")
  @PostMapping("/addauths")
  public Result addAuths(@RequestBody SysMenuRequestDTO sysMenuRequestDTO) {

    SysMenu sysMenu = new SysMenu();
    for (String auth : UpmsConstans.DEFAULT_AUTH) {
      String[] str = auth.split("_");
      StringBuilder sb = new StringBuilder();
      sb.append(sysMenuRequestDTO.getPermissionPrefix());
      sb.append(
          sysMenuRequestDTO.getPermissionPrefix().endsWith(UpmsConstans.SPLIC)
              ? str[0]
              : UpmsConstans.SPLIC.concat(str[0]));
      sysMenu.setId(null);
      sysMenu.setName(sysMenuRequestDTO.getParentName().concat(str[1]));
      sysMenu.setParentId(sysMenuRequestDTO.getParentId());
      sysMenu.setType(CommonConstants.MENU_TYPE_1);
      sysMenu.setSort(1);
      sysMenu.setPermission(sb.toString());
      sysMenuService.save(sysMenu);
    }
    return Result.success();
  }

  /**
   * 通过用户ID查询菜单权限
   *
   * @author lijx
   * @since 2022/2/25 17:19
   */
  @ApiOperation(value = "通过用户ID查询菜单权限")
  @GetMapping("/getpermissionlist/{loginId}")
  public Result getPermissionList(@PathVariable String loginId) {
    List<String> roleIds = sysRoleService.findRoleIdsByUserId(loginId);
    // 权限列表
    Set<String> permissions = new HashSet<>();
    roleIds.forEach(
        roleId -> {
          List<MenuVO> sysMenus = sysMenuService.findMenuByRoleId(roleId);
          List<String> permissionList =
              sysMenus.stream()
                  .filter(menuVo -> StrUtil.isNotEmpty(menuVo.getPermission()))
                  .map(MenuVO::getPermission)
                  .collect(Collectors.toList());
          permissions.addAll(permissionList);
        });
    return Result.success(permissions);
  }
}
